#define _CRT_SECURE_NO_WARNINGS
#include "SIngleList.h"

bool SL::isEmpty()
{
	return this == nullptr;
}


SingleList* SL::BuyNewNode(SLDataType x)
{
	SL* newnode = (SL*)malloc(sizeof(SL));
	if (newnode == nullptr)
	{
		perror("malloc fail");
		return nullptr;
	}
	newnode->data = x;
	newnode->next = nullptr;

	return newnode;
}

void SL::PushFront(SingleList*& slnode, SLDataType x)
{
	SL* head = slnode;
	SL* newnode = BuyNewNode(x);
	newnode->next = head;
	slnode = newnode;
}

void SL::PushBack(SingleList*& slnode, SLDataType x)
{
	SL* newnode = BuyNewNode(x);
	if (slnode == nullptr)
	{
		slnode = newnode;
		return;
	}
	SL* head = slnode;
	while (head->next)
	{
		head = head->next;
	}
	head->next = newnode;

}

void SL::PopFront(SingleList*& slnode)
{
	assert(!SL::isEmpty());
	auto head = this, next = this->next;
	free(head);
	slnode = next;
}

void SL::PopBack(SingleList*& slnode)
{
	assert(!SL::isEmpty());
	SL* tail = this;
	SL* prev = nullptr;
	while (tail->next)
	{
		prev = tail;
		tail = tail->next;
	}
	
	free(tail);
	if (prev == nullptr)
	{
		slnode = prev;
	}
	else
	{
		prev->next = nullptr;
	}

}
int SL::Size()
{
	int count = 0;
	auto head = this;
	while (head)
	{
		count++;
		head = head->next;
	}
	return count;
}

SLDataType SL::Tail()
{
	assert(!SL::isEmpty());
	SL* _tail = this;
	while (_tail->next)
		_tail = _tail->next;
	return _tail->data;
}
SLDataType SL::Head()
{
	assert(!SL::isEmpty());
	return this->data;
}
SL* SL::Find(SLDataType x)
{
	//assert(!SL::isEmpty());
	auto head = this;
	while (head)
	{
		if (head->data == x)
			return head;
		head = head->next;
	}
	return nullptr;
}
bool SL::Erase(SingleList*& slhead, SingleList* node)
{
	assert(!SL::isEmpty());
	SL* head = this;
	SL* prev = nullptr;
	while (head)
	{
		if (head == node)
		{
			if (prev == nullptr)
			{
				slhead = head->next;
			}
			else
			{
				slhead = prev;
				slhead->next = head->next;
			}
			free(head);
			return true;
		}
		prev = head;
		head = head->next;
	}
	return false;
}
void SL::Print()
{
	//assert(!SL::isEmpty());
	if (SL::isEmpty())
	{
		std::cout << "nullptr" << std::endl;
		return;
	}
	SL* head = this;
	while (head)
	{
		std::cout << head->data << "->";
		head = head->next;
	}
	std::cout << "nullptr" << std::endl;
}

void SL::Destroy()
{
	//assert(!SL::isEmpty());
	if (SL::isEmpty())
		return;
	SL* head = this;
	while (head)
	{
		SL* next = head->next;
		free(head);
		head = next;
	}
}

